package com.dmn.gcode.springchains;

import com.dmn.gcode.springchains.core.IOperator;

import java.util.ArrayList;
import java.util.List;

/**
 * User: dvponomarev
 * Date: 27.05.11
 */
public class ChainMasterWithFeedback extends ChainMaster {
    protected List<IChainEventListener> chainEventListeners;

    public void execute(IOperator operator) throws Throwable {
        String operatorPath = getOperatorsStackTraceString();
        String operatorName = getStackTraceOperatorName(operator);

        fireChainEvent(ChainEventType.BEFORE, operatorPath, operatorName);
        super.execute(operator);
        fireChainEvent(ChainEventType.AFTER, operatorPath, operatorName);
    }

    protected void fireChainEvent(ChainEventType eventType,
                                  String operatorPath, String operatorName) {
        if (chainEventListeners == null) {
            return;
        }
        for (IChainEventListener listener : chainEventListeners) {
            switch (eventType) {
                case BEFORE:
                    listener.onBeforeOperator(operatorPath, operatorName);
                    break;
                case AFTER:
                    listener.onAfterOperator(operatorPath, operatorName);
                    break;
                default:
                    throw new IllegalStateException(
                        "Unsupported chain event type: '" + eventType + "'.");
            }
        }
    }

    public void addChainEventListener(IChainEventListener listener) {
        if (this.chainEventListeners == null) {
            this.chainEventListeners = new ArrayList<IChainEventListener>(1);
        }
        this.chainEventListeners.add(listener);
    }

    public void clearChainEventListeners() {
        this.chainEventListeners = null;
    }

    private enum ChainEventType {
        BEFORE, AFTER
    }
}
